#include "Manager.h"


Manager::Manager(HWND wndHandle, HINSTANCE hInstance)
{
	BulletText = "";
	LineText = "";
	ScoreText = "";
	Bullets = 10;

	wHandle = wndHandle;

	srcRect.left = 0;
	srcRect.top = 0;
	srcRect.right = srcRect.left + 466;
	srcRect.bottom = srcRect.top + 307;

	destRect.left = 0;
	destRect.top = 0;
	destRect.right = destRect.left + SCREEN_WIDTH;
	destRect.bottom = destRect.top + SCREEN_HEIGHT;

	gridSrc.left = 0;
	gridSrc.top = 0;
	gridSrc.right = gridSrc.left + GRID_WIDTH;
	gridSrc.bottom = gridSrc.top + GRID_HEIGHT;

	gridDest.left = GRID_PX * 15;
	gridDest.top = GRID_PY * 15;
	gridDest.right = gridDest.left + (GRID_WIDTH * .5);
	gridDest.bottom = gridDest.top + (GRID_HEIGHT * .5);

	swapSrc.left = 0;
	swapSrc.top = 0;
	swapSrc.right = swapSrc.left + 120;
	swapSrc.bottom = swapSrc.top + 120;
	
	swapDest.left = 26 * 15;
	swapDest.top = 3 * 15;
	swapDest.right = swapDest.left + (120 * .5);
	swapDest.bottom = swapDest.top + (120 * .5);


	//Must be called before InitWindow
	if(!(dxm.init(wndHandle)))
		MessageBox(wndHandle, "DIRECTXMANAGER INIT FAILED!","DIRECTXMANAGER INIT FAILED!", NULL);
	dxm.initDInput(hInstance, wndHandle);

	background = dxm.loadSurfaceFromBitmap("background.png", 466, 307);
	gridOutline = dxm.loadSurfaceFromBitmap("T_BLOCK.bmp", 300, 600);

	srand(unsigned( time(NULL)));
	int rBlock = (rand() % (I_BLOCK - O_BLOCK + 1)) + O_BLOCK;

	grid = new Grid(&dxm); 
	tetri = new Tetrimino(rBlock); 
	hold = new Tetrimino();

	CurrX = (GRID_SX/2 - 1); 
	CurrY = 1;

	music = dxm.LoadWaveToSoundBuffer("sounds/remix.wav");;
	shot = dxm.LoadWaveToSoundBuffer("sounds/shot.wav");;
	dxm.playSoundLoop(music);

	last_t = 0.0; 
	End = false;
	score = 0;
	lines = 0;
}

Manager::~Manager()
{
	delete grid;
	delete tetri;
	delete hold;
}

void Manager::ReInit()
{
	int rBlock = (rand() % (I_BLOCK - O_BLOCK + 1)) + O_BLOCK;

	delete tetri;
	tetri = NULL;
	tetri = new Tetrimino(rBlock);

	CurrX = (GRID_SX/2 - 1);
	CurrY = 1;
	holdCount = 0;
}

void Manager::ReInitHold()
{
	CurrX = (GRID_SX/2 - 1);
	CurrY = 1;
}

bool Manager::rColl()
{
	for(int x = 0; x < P_NUM; x++)
	{
		int ty = tetri->GetPoint(x).Y + CurrY;
		int tx = tetri->GetPoint(x).X + CurrX;

		if(tx >= GRID_SX-1)
			return true;
		else
		{
			if(grid->getOcc(tx+1,ty))
				return true;
		}
	}
	return false;
}

bool Manager::lColl()
{
	for(int x = 0; x < P_NUM; x++)
	{
		int ty = tetri->GetPoint(x).Y + CurrY;
		int tx = tetri->GetPoint(x).X + CurrX;

		if(tx <= 0)
			return true;
		else
		{
			if(grid->getOcc(tx-1,ty))
				return true;
		}
	}

	return false;
}

bool Manager::tColl()
{
	for(int x = 0; x < P_NUM; x++)
	{
		int ty = tetri->GetPoint(x).Y + CurrY;
		int tx = tetri->GetPoint(x).X + CurrX;

		if(ty < 0)
			return true;
	}
	return false;
}

bool Manager::Stop()
{
	for(int x = 0; x < P_NUM; x++)
	{
		int ty = tetri->GetPoint(x).Y + CurrY;
		int tx = tetri->GetPoint(x).X + CurrX;

		if(ty >= GRID_SY-1)
			return true;
		else
		{
			if(grid->getOcc(tx,ty+1))
				return true;
		}
	}
	return false;
}

void Manager::InitDraw()
{
	grid->DrawOutline();
	Draw();
}

void Manager::Draw()
{
	dxm.beginRender();

	dxm.blitToSurface(background, &srcRect, &destRect);
	dxm.blitToSurface(gridOutline, &gridSrc, &gridDest);
	dxm.blitToSurface(gridOutline, &swapSrc, &swapDest);
	grid->DrawGrid();
	//Add GRID_PX and GRID_PY back into this calculation to make the tetrimo be in the right spot in accordance with the board
	tetri->Draw(&dxm,CurrX+GRID_PX,CurrY+GRID_PY);

	if(!hold->isNull())
		hold->Draw(&dxm,27,4);
		
	dxm.printText(390, 130, BulletText);
	dxm.printText(390, 150, LineText);
	dxm.printText(390, 170, ScoreText);

	dxm.endRender();
}

bool Manager::Input(double p_time, double c_time)
{
	int flag = 0;
	flag = dxm.readInput();

	
	if(flag & PAUSE)
	{
		MessageBox(wHandle, "Hit OK to continue", "PAUSED", NULL);
	}


	if(flag & SHOOT)
	{
		if((c_time-p_time) > SHOOT_WAIT)
		{
			DestroyBlock();
			Draw();
		}
	}

	if(flag & MOVE_LEFT)
	{
		{
			if(!lColl())
			{
				CurrX--;

				if(Stop())
					if((c_time-p_time) > IMPRINT_WAIT)
						Imprint();

				Draw();
				return true;
			}
		}
	}
	if(flag & MOVE_RIGHT)
	{
		if(!rColl())
		{
			CurrX++;

			if(Stop())
				if((c_time-p_time) > IMPRINT_WAIT)
					Imprint();
			
			Draw();
			return true;
		}
	}
	if(flag & SWAP)
	{
		if(holdCount == 0)
		{
			if(hold->isNull())
			{
				*hold = *hold + tetri;
				ReInit();
				++holdCount;
			}
			else
			{
				Tetrimino *temp;
				temp = new Tetrimino();
				*temp = *temp + tetri;
				*tetri = *tetri + hold;
				*hold = *hold + temp;
				ReInitHold();
				++holdCount;
				delete temp;
			}
		}
	}
	if(!Stop())
	{
		if((c_time-p_time) > ROTATE_WAIT)
			if(flag & FLIP)
			{
				if(tetri->getType() == 'I' && CurrY == 1)
				{
				}
				else
					tetri->RotateR();

				while(lColl())
				{
					CurrX++;
				}
				while(rColl())
				{
					CurrX--;
				}
					
				while(tColl())
				{
					CurrY++;
				}

				if(Stop())
					if((c_time-p_time) > IMPRINT_WAIT)
						Imprint();

				Draw();
				return true;
			}
	
		if(flag & DROP)
		{
			CurrY++;
			score+= 10;

			if(Stop())
				if((c_time-p_time) > IMPRINT_WAIT)
					Imprint();
			
			Draw();
			return true;
		}
	}
		
	else
	{
		if((c_time-p_time) > IMPRINT_WAIT)
			Imprint();
		UpdateRows();
	}

	return false;
		

}

void Manager::Update(double time)
{
	RECT wPos;
	GetWindowRect(wHandle, &wPos);

	POINT p;
	GetCursorPos(&p);

	mX = p.x - wPos.left;
	mY = p.y - wPos.top;

	if((time-last_t) > .5)
	{
		if(!Stop())
			CurrY++;
		else
			if((time-last_t) > IMPRINT_WAIT)
				Imprint();

		UpdateRows();

		Draw();
		
		

		last_t = time;
	}

	//prevents from crashing array
	if(Bullets >= 9999)
	{
		Bullets = 9999;
	}

	//uses bulletparse to parse digits into characters. 5 element array
	itoa(Bullets, bulletparse , 10);
	BulletText = bulletparse;
	BulletText = "Bullets: " + BulletText;

	//prevents from crashing array
	if(lines >= 9999)
	{	
		lines = 9999;
	}
	
	//uses bulletparse to parse digits into characters. 5 element array
	itoa(lines, bulletparse, 10);
	LineText = bulletparse;
	LineText = "Lines: " + LineText;

	//prevents from crashing array, thats 999,999,999... IT'S OVER 9 HUNDRED MILLION!
	if(score >= 999999999)
	{
		score = 999999999;
	}

	//uses point parse to turn the digits into characters, 10 element array
	itoa(score, pointparse, 10);
	ScoreText = pointparse;
	ScoreText = "Score: " + ScoreText;

}

void Manager::UpdateRows()
{
	int row = grid->FullRow();

	while(row != 0)
	{
		grid->ClearRow(row);
		score+= 100;
		lines++;
		row = grid->FullRow();
		Bullets++;
	}
}

void Manager::Imprint()
{
	if(grid->StopTetri(CurrX, CurrY, *tetri))
		ReInit();
	else
		End = true;
}

void Manager::DestroyBlock()
{
	if(Bullets > 0)
	{
		
		if(grid->ClearBlock(mX,mY))
		{
			Bullets  = Bullets - 1;
			dxm.playSound(shot);
		}
	}
}